package com.love.marriage.userInfo.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.love.marriage.cloud.service.WechatService;
import com.love.marriage.common.enums.ResultEnum;
import com.love.marriage.common.exceptions.UserException;
import com.love.marriage.common.redisKey.CodeKey;
import com.love.marriage.common.vo.SecurityUser;
import com.love.marriage.oss.service.FileInfoService;
import com.love.marriage.oss.vo.FileInfoVo;
import com.love.marriage.userActivityInfo.mapper.UserActivityInfoMapper;
import com.love.marriage.userActivityInfo.vo.UserActivityInfoVo;
import com.love.marriage.userBehaviorInfo.service.UserBehaviorInfoService;
import com.love.marriage.userBehaviorInfo.vo.UserBehaviorInfoStatisticsVo;
import com.love.marriage.userBehaviorInfo.vo.UserBehaviorInfoVo;
import com.love.marriage.userInfo.entity.UserInfo;
import com.love.marriage.userInfo.mapper.UserInfoMapper;
import com.love.marriage.userInfo.service.UserInfoService;
import com.love.marriage.userInfo.vo.*;
import com.love.marriage.userPartnerPreferences.vo.UserPartnerPreferencesVo;
import com.love.marriage.userProfileInfo.vo.UserProfileInfoVo;
import com.love.marriage.userRechargeRecordInfo.vo.UserRechargeHierarchyQueryParam;
import com.love.marriage.userRechargeRecordInfo.vo.UserRechargeHierarchyVo;
import com.love.marriage.utils.RedisUtils;
import com.love.marriage.utils.StringUtils;
import com.love.marriage.utils.UserUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * description:  用户表服务实现类
 * author:       mybatisPlus
 * createDate:   2024-10-11 22:04:00
 * version:      1.0.0
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserInfoServiceImp extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    private final UserInfoMapper userInfoMapper;

    @Value(value = "${defaultPassword}")
    private String defaultPassword;

    private final RedisUtils redisUtils;

    private final FileInfoService fileInfoService;

    private final UserBehaviorInfoService userBehaviorInfoService;

    private final WechatService wechatService;

    private final UserActivityInfoMapper userActivityInfoMapper;

    @PostConstruct
    public void initUserCode() {
        redisUtils.setIfAbsent("CodeKey:incr:userCode:user", "500");
    }


    @Override
    public Page<UserInfoVo> getPage(Long pageNum, Long pageSize, UserInfoVo userInfoVo) {
        Page<UserInfoVo> page = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize);
        Page<UserInfoVo> res = userInfoMapper.getPage(page, userInfoVo);
        if (res != null && res.getRecords() != null && !res.getRecords().isEmpty()) {
            List<Long> userIds = res.getRecords().stream().map(UserInfoVo::getId).collect(Collectors.toList());
            List<MemberAboutVo> memberAboutList = userInfoMapper.getMemberAboutListByUserIds(userIds);
            final Map<Long, MemberAboutVo> memberAboutMap =
                    (memberAboutList == null || memberAboutList.isEmpty())
                            ? java.util.Collections.emptyMap()
                            : memberAboutList.stream().collect(Collectors.toMap(MemberAboutVo::getId, item -> item, (a, b) -> a));
            res.getRecords().forEach(user -> {
                if (user.getAvatar() != null) {
                    try {
                        user.setPersonAvatar(fileInfoService.queryFileInfo(user.getAvatar()));
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
                if (memberAboutMap.get(user.getId()) != null) {
                    MemberAboutVo memberAboutVo = memberAboutMap.get(user.getId());
                    user.setSingleFlag(memberAboutVo.getUserProfileInfoVo() == null ? false : true);
                    user.setUserMembershipInfoVo(memberAboutVo.getUserMembershipInfoVo());
                    user.setMatchmakerInfoVo(memberAboutVo.getMatchmakerInfoVo());
                    user.setOfflineServiceProviderVo(memberAboutVo.getOfflineServiceProviderVo());
                    user.setMembershipFlag(memberAboutVo.getMembershipFlag());
                    user.setMatchmakerFlag(memberAboutVo.getMatchmakerFlag());
                    user.setPartnerFlag(memberAboutVo.getPartnerFlag());
                    user.setIdentityVerificationVo(memberAboutVo.getIdentityVerificationVo());
                    user.setUserProfileInfoVo(memberAboutVo.getUserProfileInfoVo());
                } else {
                    user.setSingleFlag(false);
                    user.setMembershipFlag(false);
                    user.setMatchmakerFlag(false);
                    user.setPartnerFlag(false);
                }
            });
        }
        return res;
    }

    @Override
    public Page<UserVo> getUserPage(Long pageNum, Long pageSize, UserSearchInfoVo userInfoVo) {
        Page<UserVo> page = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize);
        LocalDate startTime = null;
        LocalDate endTime = null;
        if (userInfoVo == null) {
            userInfoVo = new UserSearchInfoVo();
        }
        // 根据 generation 设置出生日期范围
        if (StringUtils.isNotBlank(userInfoVo.getGeneration()) && !"none".equals(userInfoVo.getGeneration())) {
            switch (userInfoVo.getGeneration()) {
                case "50s":
                    startTime = LocalDate.of(1950, 1, 1);
                    endTime = LocalDate.of(1959, 12, 31);
                    break;
                case "60s":
                    startTime = LocalDate.of(1960, 1, 1);
                    endTime = LocalDate.of(1969, 12, 31);
                    break;
                case "70s":
                    startTime = LocalDate.of(1970, 1, 1);
                    endTime = LocalDate.of(1979, 12, 31);
                    break;
                case "80s":
                    startTime = LocalDate.of(1980, 1, 1);
                    endTime = LocalDate.of(1989, 12, 31);
                    break;
                case "90s":
                    startTime = LocalDate.of(1990, 1, 1);
                    endTime = LocalDate.of(1999, 12, 31);
                    break;
                case "00s":
                    startTime = LocalDate.of(2000, 1, 1);
                    endTime = LocalDate.of(2009, 12, 31);
                    break;
                case "10s":
                    startTime = LocalDate.of(2010, 1, 1);
                    endTime = LocalDate.of(2019, 12, 31);
                    break;
                case "20s":
                    startTime = LocalDate.of(2020, 1, 1);
                    endTime = LocalDate.of(2029, 12, 31);
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported generation: " + userInfoVo.getGeneration());
            }
        }
        if (userInfoVo.getAges() != null && !userInfoVo.getAges().isEmpty()) {
            LocalDate today = LocalDate.now();
            // 计算最大年龄的起始日期 (maxAge 年前的 1 月 1 日)
            startTime = today.minusYears(userInfoVo.getAges().get(1)).withMonth(1).withDayOfMonth(1);
            // 计算最小年龄的结束日期 (minAge 年前的 12 月 31 日)
            endTime = today.minusYears(userInfoVo.getAges().get(0)).withMonth(12).withDayOfMonth(31);
        }
        SecurityUser loginUser = UserUtils.getLoginUser();
        Long loginUserId = null;
        if (loginUser != null) {
            loginUserId = loginUser.getId();
        }
        Page<UserVo> list = userInfoMapper.getUserPage(page, userInfoVo, startTime, endTime, loginUserId, "list");
        if (list != null && list.getRecords() != null && !list.getRecords().isEmpty()) {
            list.getRecords().forEach(user -> {
                if (user.getAvatar() != null) {
                    try {
                        user.setPersonAvatar(fileInfoService.queryFileInfo(user.getAvatar()));
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        return list;
    }

    @Override
    public UserInfoVo queryUserInfo(Long id) {
        UserInfoVo userInfoVo = userInfoMapper.queryUserInfo(id);
        if (userInfoVo == null) {
            return null;
        }
        try {
            if (userInfoVo.getAvatar() != null) {
                userInfoVo.setPersonAvatar(fileInfoService.queryFileInfo(userInfoVo.getAvatar()));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return userInfoVo;
    }

    @Override
    public UserInfoVo queryUserInfoByPhone(String phone) {
        UserInfoVo userInfoVo = userInfoMapper.queryUserInfoByPhone(phone);
        if (userInfoVo == null) {
            return null;
        }
        try {
            if (userInfoVo.getAvatar() != null) {
                userInfoVo.setPersonAvatar(fileInfoService.queryFileInfo(userInfoVo.getAvatar()));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return userInfoVo;
    }

    @Override
    public UserVo queryUser(Long id) throws Exception {
        UserVo userVo = userInfoMapper.queryUser(id, "detail");
        if (userVo == null) {
            return null;
        }
        if (userVo.getAvatar() != null) {
            try {
                userVo.setPersonAvatar(fileInfoService.queryFileInfo(userVo.getAvatar()));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        if (userVo.getUserProfileInfoVo() != null &&
                userVo.getUserProfileInfoVo().getPersonalImageryInfoVoList() != null &&
                !userVo.getUserProfileInfoVo().getPersonalImageryInfoVoList().isEmpty()
        ) {
            userVo.getUserProfileInfoVo().getPersonalImageryInfoVoList().forEach(item -> {
                try {
                    item.setFileInfoVo(fileInfoService.queryFileInfo(item.getFileId()));
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
        }
        // 如果当前人不等于查看人，就记录查看信息
        // 并且查询当前人和被查询人是否是喜欢、收藏关系
        SecurityUser loginUser = UserUtils.getLoginUser();
        if (loginUser != null) {
            if (!Objects.equals(id, loginUser.getId())) {
                UserBehaviorInfoVo userBehaviorInfoVo = new UserBehaviorInfoVo();
                userBehaviorInfoVo.setActionType("view");
                userBehaviorInfoVo.setUserId(loginUser.getId());
                userBehaviorInfoVo.setActorId(id);
                userBehaviorInfoService.addUserBehaviorInfo(userBehaviorInfoVo);
                UserBehaviorInfoVo query = new UserBehaviorInfoVo();
                query.setUserId(loginUser.getId());
                query.setActorId(id);
                List<UserBehaviorInfoVo> userBehaviorInfoVos = userBehaviorInfoService.queryUserBehaviorInfo(query);
                if (userBehaviorInfoVos != null && !userBehaviorInfoVos.isEmpty()) {
                    userVo.setLike(getLike(userBehaviorInfoVos, "like"));
                    userVo.setCollect(getLike(userBehaviorInfoVos, "collect"));
                }
                userVo.setUserMembershipInfoVo(null);
            } else {
                UserBehaviorInfoStatisticsVo userBehaviorInfoStatisticsVo = userBehaviorInfoService.queryUserBehaviorStatisticsInfo(loginUser.getId());
                // 如果是一个人表示是查看自己信息，需要查询统计信息
                userVo.setUserBehaviorInfoStatisticsVo(userBehaviorInfoStatisticsVo);
            }
        }
        return userVo;
    }

    @Override
    public UserVo queryNewUser(Long id) throws Exception {
        UserVo userVo = userInfoMapper.queryUser(id, "detail");
        log.info("用户数据 ===========================：{}" , JSONObject.toJSONString(userVo));
        if (userVo == null) {
            return null;
        }
        if (userVo.getAvatar() != null) {
            try {
                userVo.setPersonAvatar(fileInfoService.queryFileInfo(userVo.getAvatar()));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        if (userVo.getUserProfileInfoVo() != null) {
            UserProfileInfoVo userProfileInfoVo = userVo.getUserProfileInfoVo();
            if (userProfileInfoVo.getPersonalImageryInfoVoList() != null &&
                    !userVo.getUserProfileInfoVo().getPersonalImageryInfoVoList().isEmpty()) {
                userProfileInfoVo.getPersonalImageryInfoVoList().forEach(item -> {
                    try {
                        item.setFileInfoVo(fileInfoService.queryFileInfo(item.getFileId()));
                    } catch (Exception e) {
                        log.error("查询个人形象图片失败", e);
                    }
                });
            }
            if (userProfileInfoVo.getWechatQrCodeId() != null) {
                try {
                    FileInfoVo fileInfoVo = fileInfoService.queryFileInfo(userProfileInfoVo.getWechatQrCodeId());
                    userProfileInfoVo.setWechatQrCodeFile(fileInfoVo);
                } catch (Exception e) {
                    log.error("查询微信二维码失败", e);
                }
            }
            // 查询分享照片的预览url
            if (userProfileInfoVo.getSharePhotoId() != null) {
                FileInfoVo fileInfoVo = fileInfoService.queryFileInfo(userProfileInfoVo.getSharePhotoId());
                if (fileInfoVo != null) {
                    userProfileInfoVo.setSharePhotoUrl(fileInfoVo.getPreUrl());
                }
            }
        }
        // 如果用户征婚资料没有数据，或者征婚资料没有填写昵称（默认算作没有维护征婚资料），则取活动中的数据
        if (userVo.getUserProfileInfoVo() == null || StringUtils.isBlank(userVo.getUserProfileInfoVo().getNickname())) {
            // 如果用户档案信息没有值，或者用户档案昵称为空时，获取活动中的数据
            UserActivityInfoVo userActivityInfoVo = userActivityInfoMapper.queryUserActivityInfoByUser(userVo.getId());
            if (userActivityInfoVo != null) {
                UserProfileInfoVo userProfileInfoVo = userVo.getUserProfileInfoVo();
                if (userProfileInfoVo == null) {
                    userProfileInfoVo = new UserProfileInfoVo();
                }
                userProfileInfoVo.setGender(userActivityInfoVo.getGender());
                userProfileInfoVo.setProfession(userActivityInfoVo.getProfession());
                userProfileInfoVo.setProfessionName(userActivityInfoVo.getProfessionName());
                userProfileInfoVo.setIncomeStatus(userActivityInfoVo.getIncomeStatus());
                userProfileInfoVo.setIncomeStatusName(userActivityInfoVo.getIncomeStatusName());
                userProfileInfoVo.setProvinceId(userActivityInfoVo.getProvinceId());
                userProfileInfoVo.setCityId(userActivityInfoVo.getCityId());
                userProfileInfoVo.setDistrictId(userActivityInfoVo.getDistrictId());
                userProfileInfoVo.setProvinceName(userActivityInfoVo.getProvinceName());
                userProfileInfoVo.setCityName(userActivityInfoVo.getCityName());
                userProfileInfoVo.setDistrictName(userActivityInfoVo.getDistrictName());
                userProfileInfoVo.setHeight(userActivityInfoVo.getHeight());
                userProfileInfoVo.setWeight(userActivityInfoVo.getWeight());
                userProfileInfoVo.setBirthYearMonth(userActivityInfoVo.getBirthYearMonth());
                userVo.setUserProfileInfoVo(userProfileInfoVo);
            }
        }
        // 如果当前人不等于查看人，就记录查看信息
        // 并且查询当前人和被查询人是否是喜欢、收藏关系
        SecurityUser loginUser = UserUtils.getLoginUser();
        if (loginUser != null) {
            if (!Objects.equals(id, loginUser.getId())) {
                UserBehaviorInfoVo userBehaviorInfoVo = new UserBehaviorInfoVo();
                userBehaviorInfoVo.setActionType("view");
                userBehaviorInfoVo.setUserId(loginUser.getId());
                userBehaviorInfoVo.setActorId(id);
                userBehaviorInfoService.addUserBehaviorInfo(userBehaviorInfoVo);
                UserBehaviorInfoVo query = new UserBehaviorInfoVo();
                query.setUserId(loginUser.getId());
                query.setActorId(id);
                List<UserBehaviorInfoVo> userBehaviorInfoVos = userBehaviorInfoService.queryUserBehaviorInfo(query);
                if (userBehaviorInfoVos != null && !userBehaviorInfoVos.isEmpty()) {
                    userVo.setLike(getLike(userBehaviorInfoVos, "like"));
                    userVo.setCollect(getLike(userBehaviorInfoVos, "collect"));
                }
                userVo.setUserMembershipInfoVo(null);
                log.info("当前用户id为：{}，被查询用户id为：{}, userVo:{}", loginUser.getId(), id, JSONObject.toJSONString(userVo));
                if (StringUtils.isNotBlank(userVo.getWechatGzhOpenid())) {
                    try {
                        wechatService.sentUserMessage(userVo.getWechatGzhOpenid(), id, userVo.getCode(), "detail");
                    } catch (Exception e) {
                        log.error("发送消息失败:{}", e.getMessage());
                    }
                }
            } else {
                UserBehaviorInfoStatisticsVo userBehaviorInfoStatisticsVo = userBehaviorInfoService.queryUserBehaviorStatisticsInfo(loginUser.getId());
                // 如果是一个人表示是查看自己信息，需要查询统计信息
                userVo.setUserBehaviorInfoStatisticsVo(userBehaviorInfoStatisticsVo);
            }
        }
        return userVo;
    }

    @Override
    public UserVo queryByLocalImId(Long localImId) throws Exception {
        UserVo userVo = userInfoMapper.queryByLocalImId(localImId, "detail");
        if (userVo != null) {
            if (userVo.getAvatar() != null) {
                try {
                    userVo.setPersonAvatar(fileInfoService.queryFileInfo(userVo.getAvatar()));
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            if (userVo.getUserProfileInfoVo() != null &&
                    userVo.getUserProfileInfoVo().getPersonalImageryInfoVoList() != null &&
                    !userVo.getUserProfileInfoVo().getPersonalImageryInfoVoList().isEmpty()
            ) {
                userVo.getUserProfileInfoVo().getPersonalImageryInfoVoList().forEach(item -> {
                    try {
                        item.setFileInfoVo(fileInfoService.queryFileInfo(item.getFileId()));
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                });
            }
        }
        return userVo;
    }

    private boolean getLike(List<UserBehaviorInfoVo> list, String type) {
        return list.stream()
                .anyMatch(behavior -> type.equals(behavior.getActionType()));
    }

    @Override
    public UserInfoVo addUserInfo(UserInfoVo userInfoVo) {
        LambdaQueryWrapper<UserInfo> query = Wrappers.<UserInfo>lambdaQuery()
                .eq(UserInfo::getPhone, userInfoVo.getPhone())
                .eq(UserInfo::getDeleteFlag, 0);
        UserInfo db = userInfoMapper.selectOne(query);
        if (db != null) {
            throw new UserException(ResultEnum.USER_PHONE_EXISTS);
        }
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userInfoVo, userInfo);
        // 获取redis中存储的自增key 501
        Long curNum = redisUtils.increase(CodeKey.codeIncrKey, "user");
        userInfo.setCodeNum(curNum);
        // 获取用户的性别，男：0，女：1，未知：2，放在501的个位和十位之间
        // 获取用户来源，如果introUserId为空，则1：否则为2，放在501的十位和百位之间
        userInfo.setSource(userInfoVo.getIntroUserId() == null ? 1 : 2);
        userInfo.setCode(getUserCode(String.valueOf(curNum), "2", userInfoVo.getIntroUserId() == null ? 1 : 2));
        // 如果密码是空，则添加默认密码
        String password = userInfo.getPassword() == null ? defaultPassword : userInfo.getPassword();
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        userInfo.setPassword(encoder.encode(password));
        userInfoMapper.insert(userInfo);
        UserInfoVo res = new UserInfoVo();
        BeanUtils.copyProperties(userInfo, res);
        return res;
    }

    @Override
    public UserInfoVo updateUserInfo(UserInfoVo userInfoVo) {
        LambdaQueryWrapper<UserInfo> query = Wrappers.<UserInfo>lambdaQuery()
                .eq(UserInfo::getPhone, userInfoVo.getPhone())
                .ne(UserInfo::getId, userInfoVo.getId())
                .eq(UserInfo::getDeleteFlag, 0);
        UserInfo db = userInfoMapper.selectOne(query);
        if (db != null) {
            throw new UserException(ResultEnum.USER_PHONE_EXISTS);
        }
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userInfoVo, userInfo);
        userInfoMapper.updateById(userInfo);
        return userInfoVo;
    }

    /**
     * @param unionId
     * @param openId
     * @description: 根据unionid，关联公众号openId
     * @author: alex
     * @return: com.love.marriage.userInfo.vo.UserInfoVo
     */

    @Override
    public Boolean updateUserInfo(String unionId, String openId) {
        LambdaQueryWrapper<UserInfo> query = Wrappers.<UserInfo>lambdaQuery()
                .eq(UserInfo::getWechatUnionid, unionId)
                .eq(UserInfo::getDeleteFlag, 0);
        UserInfo db = userInfoMapper.selectOne(query);
        if (db == null) {
            return false;
        }
        db.setWechatGzhOpenid(openId);
        userInfoMapper.updateById(db);
        return true;
    }

    @Override
    public Boolean deleteUserInfo(String ids) {
        if (StringUtils.isEmpty(ids)) {
            return true;
        }
        List<String> idArr = Arrays.asList(ids.split(","));
        userInfoMapper.deleteBatchIds(idArr);
        return true;
    }

    public String getUserCode(String num, String sex, Integer source) {
        if (num == null) {
            num = "500";
        }
        return num.substring(0, num.length() - 2) // 取自增编号的百位之前部分
                + source // 设置用户来源
                + num.charAt(num.length() - 2)
                + sex  // 设置用户性别
                + num.substring(num.length() - 1); // 保留自增编号的个位
    }

    @Override
    public void refreshUserCode(Long userId, String sex) {
        UserInfo dbUser = this.getById(userId);
        if (dbUser != null && !"1".equals(dbUser.getCode())) {
            if ("2".equals(dbUser.getCode().substring(dbUser.getCode().length() - 2)) ||
                    !sex.equals(dbUser.getCode().substring(dbUser.getCode().length() - 2))) {
                Long curNum;
                if (dbUser.getCodeNum() == null) {
                    curNum = redisUtils.increase(CodeKey.codeIncrKey, "user");
                } else {
                    curNum = dbUser.getCodeNum();
                }
                // 获取用户的性别，男：0，女：1，未知：2，放在501的个位和十位之间
                // 获取用户来源，如果introUserId为空，则1：否则为2，放在501的十位和百位之间
                dbUser.setCode(getUserCode(String.valueOf(curNum), sex, dbUser.getSource()));
                this.updateById(dbUser);
            }
        }
    }

    @Override
    public FileInfoVo addAvatar(Long userId, MultipartFile file) throws Exception {
        FileInfoVo fileInfoVo = fileInfoService.addFileInfo("common", file);
        UserInfo dbUser = getById(userId);
        dbUser.setAvatar(fileInfoVo.getId());
        dbUser.updateById();
        return fileInfoVo;
    }

    @Override
    public UserCountVo queryUserMemberInfo() {
        return userInfoMapper.queryUserMemberInfo();
    }

    @Override
    public UserCountVo queryUserStatistics() {
        return userInfoMapper.queryUserStatistics();
    }

    @Override
    public List<UserDataUserVo> queryDayUserInfo() {
        return userInfoMapper.queryDayUserInfo();
    }

    @Override
    public List<UserInfoVo> queryNoticeUserInfo() {
        return userInfoMapper.queryNoticeUserInfo();
    }

    @Override
    public List<UserInfoVo> getInvite(UserInfoVo userInfoVo) {
        return userInfoMapper.getInvite(userInfoVo);
    }

    @Override
    public Page<UserReduceInfoVo> queryUserReduceInfo(Long pageNum, Long pageSize, UserInfoVo userInfoVo) {
        Page<UserReduceInfoVo> page = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize);
        return userInfoMapper.queryUserReduceInfoNew(page, userInfoVo);
    }

    @Override
    public Page<UserReduceInfoVo> queryUserReduceDetailInfo(Long pageNum, Long pageSize, UserInfoVo userInfoVo) {
        Page<UserReduceInfoVo> page = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize);
        return userInfoMapper.queryUserReduceDetailInfo(page, userInfoVo);
    }

    @Override
    public List<UserInfoVo> queryUserList(UserInfoVo userInfoVo) throws Exception {
        return userInfoMapper.queryUserList(userInfoVo);
    }

    @Override
    public Page<UserRechargeHierarchyVo> queryUserRechargeHierarchyPage(Long pageNum,
                                                                        Long pageSize,
                                                                        UserRechargeHierarchyQueryParam param) {
        Page<UserRechargeHierarchyVo> page = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize);
        Page<UserRechargeHierarchyVo> res = userInfoMapper.queryUserRechargeHierarchyPage(page, param);
        return res;
    }

    @Override
    public List<UserRechargeHierarchyVo> queryUserRechargeHierarchyList(UserRechargeHierarchyQueryParam param) {
        return userInfoMapper.queryUserRechargeHierarchyList(param);
    }

    @Override
    public void exportUserRechargeHierarchyExcel(UserRechargeHierarchyQueryParam param, HttpServletResponse response) {
        List<UserRechargeHierarchyVo> list = queryUserRechargeHierarchyList(param);
        // easypoi注解不支持get方法导出，需手动赋值
        for (UserRechargeHierarchyVo vo : list) {
            vo.setTotalCommission(vo.getTotalCommission());
            vo.setLevelName(vo.getLevel() == 2 ? "直推" : "间推");
        }
        try {
            String fileName = URLEncoder.encode("用户流水.xlsx", "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName);
            ExportParams exportParams = new ExportParams("用户流水统计", "用户流水");
            Workbook workbook = ExcelExportUtil.exportExcel(exportParams, UserRechargeHierarchyVo.class, list);
            workbook.write(response.getOutputStream());
            workbook.close();
        } catch (Exception e) {
            throw new RuntimeException("导出失败", e);
        }
    }

    @Override
    public InviteCommissionVo inviteCommissionDetail(UserRechargeHierarchyQueryParam param) {
        InviteCommissionVo inviteCommissionDetailVo = new InviteCommissionVo();
        List<InviteCommissionDetailVo> totals = userInfoMapper.queryInviteTotalCommission(param);
        if (totals != null && !totals.isEmpty()) {
            totals.forEach(item -> {
                switch (item.getLevel()) {
                    case 2:
                        inviteCommissionDetailVo.setZtCommission(item.getCommissionAmount());
                        inviteCommissionDetailVo.setZtAmount(item.getAmount());
                        inviteCommissionDetailVo.setZtCount(item.getCount());
                        break;
                    case 3:
                        inviteCommissionDetailVo.setJtCommission(item.getCommissionAmount());
                        inviteCommissionDetailVo.setJtAmount(item.getAmount());
                        inviteCommissionDetailVo.setJtCount(item.getCount());
                }
            });
        }
        List<InviteCommissionDetailVo> list = userInfoMapper.queryInviteCommissionDetailList(param);
        if (list != null && !list.isEmpty()) {
            inviteCommissionDetailVo.setZtInviteCommissionDetailList(
                    list.stream().filter(item -> item.getLevel() == 2).collect(Collectors.toList()));
            inviteCommissionDetailVo.setJtInviteCommissionDetailList(
                    list.stream().filter(item -> item.getLevel() == 3).collect(Collectors.toList()));
        }
        return inviteCommissionDetailVo;
    }

    /**
     * 导出用户信息（包含会员、红娘、合伙人信息）
     */
    @Override
    public void exportUserInfo(UserInfoVo userInfoVo, HttpServletResponse response) {
        try {
            // 查询用户列表
            List<UserInfoVo> userList = userInfoMapper.queryUserList(userInfoVo);
            
            // 批量获取用户聚合信息
            List<Long> userIds = userList.stream().map(UserInfoVo::getId).collect(Collectors.toList());
            List<MemberAboutVo> memberAboutList = userInfoMapper.getMemberAboutListByUserIds(userIds);
            final Map<Long, MemberAboutVo> memberAboutMap =
                    (memberAboutList == null || memberAboutList.isEmpty())
                            ? java.util.Collections.emptyMap()
                            : memberAboutList.stream().collect(Collectors.toMap(MemberAboutVo::getId, item -> item, (a, b) -> a));
            
            // 转换为导出VO
            List<UserInfoExportVo> exportList = userList.stream().map(user -> {
                UserInfoExportVo exportVo = new UserInfoExportVo();
                exportVo.setCode(user.getCode());
                exportVo.setPhone(user.getPhone());
                exportVo.setStatus("1".equals(user.getStatus()) ? "激活" : "失效");
                exportVo.setSingleFlag(Boolean.TRUE.equals(user.getSingleFlag()) ? "是" : "否");
                
                // 填充聚合信息
                if (memberAboutMap.get(user.getId()) != null) {
                    MemberAboutVo about = memberAboutMap.get(user.getId());
                    exportVo.setMembershipFlag(Boolean.TRUE.equals(about.getMembershipFlag()) ? "是" : "否");
                    exportVo.setMembershipName(about.getMembershipName()); // Add this line to set membership name
                    exportVo.setMembershipExpireTime(about.getUserMembershipInfoVo() != null ? about.getUserMembershipInfoVo().getEndTime() : null);
                    exportVo.setMatchmakerFlag(Boolean.TRUE.equals(about.getMatchmakerFlag()) ? "是" : "否");
                    exportVo.setMatchmakerNo(about.getMatchmakerInfoVo() != null ? about.getMatchmakerInfoVo().getNo() : null);
                    exportVo.setMatchmakerPositionLevelName(about.getMatchmakerInfoVo() != null ? about.getMatchmakerInfoVo().getPositionLevel() : null);
                    exportVo.setPartnerFlag(Boolean.TRUE.equals(about.getPartnerFlag()) ? "是" : "否");
                    exportVo.setPartnerTypeName(about.getOfflineServiceProviderVo() != null ? about.getOfflineServiceProviderVo().getPartnerTypeName() : null);
                    exportVo.setPartnerStartTime(about.getOfflineServiceProviderVo() != null ? about.getOfflineServiceProviderVo().getStartTime() : null);
                    exportVo.setPartnerEndTime(about.getOfflineServiceProviderVo() != null ? about.getOfflineServiceProviderVo().getEndTime() : null);
                }
                
                return exportVo;
            }).collect(Collectors.toList());
            
            // 生成Excel文件
            ExportParams exportParams = new ExportParams("用户信息", "用户信息");
            Workbook workbook = ExcelExportUtil.exportExcel(exportParams, UserInfoExportVo.class, exportList);
            
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("用户信息_" + System.currentTimeMillis() + ".xlsx", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
            
            // 写入响应流
            workbook.write(response.getOutputStream());
            workbook.close();
        } catch (Exception e) {
            log.error("导出用户信息失败", e);
            throw new RuntimeException("导出失败", e);
        }
    }

    /**
     * 获取用户所有信息（包含会员、红娘、合伙人、实名认证信息）
     */
    @Override
    public Page<UserInfoVo> getUserAllInfo(Long pageNum, Long pageSize, UserAllQueryVo userAllQueryVo) {
        Page<UserInfoVo> page = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize);
        return userInfoMapper.getUserAllInfo(page, userAllQueryVo);
    }

    /**
     * 导出用户完整信息（包含会员、红娘、合伙人、实名认证、用户资料信息）
     */
    @Override
    public void exportUserAllInfo(UserAllQueryVo userAllQueryVo, HttpServletResponse response) {
        try {
            // 查询所有用户完整信息（不分页）
            Page<UserInfoVo> page = new Page<>(1, Integer.MAX_VALUE);
            Page<UserInfoVo> result = userInfoMapper.getUserAllInfo(page, userAllQueryVo);
            List<UserInfoVo> userList = result.getRecords();
            
            // 转换为导出VO
            List<UserAllInfoExportVo> exportList = userList.stream().map(user -> {
                UserAllInfoExportVo exportVo = new UserAllInfoExportVo();
                
                // 基本信息 - 按照前端columns顺序
                exportVo.setCode(user.getCode());
                exportVo.setPhone(user.getPhone());
                String sourceName = "";
                if (user.getSource() != null) {
                    switch (user.getSource()) {
                        case 1:
                            sourceName = "官方来源";
                            break;
                        case 2:
                            sourceName = "红娘";
                            break;
                        case 3:
                            sourceName = "婚介所";
                            break;
                    }
                }
                exportVo.setSource(sourceName);
                exportVo.setWechatGzhOpenid(user.getWechatGzhOpenid());
                exportVo.setInstroPhone(user.getInstroPhone());
                exportVo.setInstroCode(user.getInstroCode());
                // 实名认证信息
                if (user.getIdentityVerificationVo() != null) {
                    exportVo.setRealName(user.getIdentityVerificationVo().getName());
                    exportVo.setIdCardNumber(user.getIdentityVerificationVo().getIdCardNumber());
                }
                
                // 用户资料信息
                if (user.getUserProfileInfoVo() != null) {
                    UserProfileInfoVo profile = user.getUserProfileInfoVo();
                    exportVo.setNickName(profile.getNickname());
                    
                    // 性别处理：0是男，1是女
                    if ("0".equals(profile.getGender())) {
                        exportVo.setGender("男");
                    } else if ("1".equals(profile.getGender())) {
                        exportVo.setGender("女");
                    } else {
                        exportVo.setGender("");
                    }
                    
                    exportVo.setBirthYearMonth(profile.getBirthYearMonth());
                    
                    // 安全处理数值类型转换
                    if (profile.getHeight() != null) {
                        exportVo.setHeight(profile.getHeight().intValue());
                    }
                    if (profile.getWeight() != null) {
                        exportVo.setWeight(profile.getWeight().intValue());
                    }
                    
                    // 所在地通过省市县关联显示
                    String residence = "";
                    if (profile.getProvinceName() != null) residence += profile.getProvinceName();
                    if (profile.getCityName() != null) residence += "/" + profile.getCityName();
                    if (profile.getDistrictName() != null) residence += "/" + profile.getDistrictName();
                    exportVo.setResidence(residence.isEmpty() ? "" : residence);
                    
                    exportVo.setMaritalStatus(profile.getMaritalStatusName());
                    exportVo.setEducation(profile.getEducationLevelName());
                    exportVo.setOccupation(profile.getProfessionName());
                    exportVo.setAnnualIncome(profile.getIncomeStatusName());
                    exportVo.setCarHouseStatus(profile.getCarHouseStatusName());
                    exportVo.setSchoolName(profile.getSchoolName());
                    exportVo.setEducationType(profile.getEducationTypeName());
                    exportVo.setPersonalIntroduction(profile.getSpecialNote());
                    exportVo.setLoveView(profile.getLoveView());
                    exportVo.setIdealPartner(profile.getIdealPartner());
                    exportVo.setContactPhone(profile.getContactPhone());
                    exportVo.setZodiac(profile.getZodiacName());
                    exportVo.setShowPhone(Boolean.TRUE.equals(profile.getShowPhone()) ? "是" : "否");
                    exportVo.setShowWechat(Boolean.TRUE.equals(profile.getShowWechat()) ? "是" : "否");
                    exportVo.setAutoExchangeContact(Boolean.TRUE.equals(profile.getAutoExchangeContact()) ? "是" : "否");
                }
                
                // 择偶要求信息
                if (user.getUserProfileInfoVo() != null && user.getUserProfileInfoVo().getUserPartnerPreferencesVo() != null) {
                    UserPartnerPreferencesVo pref = user.getUserProfileInfoVo().getUserPartnerPreferencesVo();
                    if (pref.getAgeFrom() != null && pref.getAgeTo() != null) {
                        exportVo.setIdealAgeRange(pref.getAgeFrom() + "-" + pref.getAgeTo());
                    }
                    if (pref.getHeightFrom() != null && pref.getHeightTo() != null) {
                        exportVo.setIdealHeightRange(pref.getHeightFrom() + "-" + pref.getHeightTo());
                    }
                    if (pref.getWeightFrom() != null && pref.getWeightTo() != null) {
                        exportVo.setIdealWeightRange(pref.getWeightFrom() + "-" + pref.getWeightTo());
                    }
                    exportVo.setIdealEducation(pref.getEducationLevelName());
                    exportVo.setIdealProfession(pref.getProfessionName());
                    exportVo.setIdealIncomeRange(pref.getIncomeRangeName());
                    exportVo.setIdealHousingCarStatus(pref.getHousingCarStatusName());
                    exportVo.setIdealMaritalStatus(pref.getMaritalStatusName());
                    
                    // 组合地区信息
                    String region = "";
                    if (pref.getProvinceName() != null) region += pref.getProvinceName();
                    if (pref.getCityName() != null) region += "/" + pref.getCityName();
                    if (pref.getDistrictName() != null) region += "/" + pref.getDistrictName();
                    exportVo.setIdealLocation(region.isEmpty() ? "不限" : region);
                }
                
                // 会员信息
                exportVo.setMembershipFlag(Boolean.TRUE.equals(user.getMembershipFlag()) ? "是" : "否");
                exportVo.setMembershipName(user.getMembershipName()); // Add this line to set membership name
                if (user.getUserMembershipInfoVo() != null) {
                    exportVo.setMembershipStartTime(user.getUserMembershipInfoVo().getStartTime());
                    exportVo.setMembershipEndTime(user.getUserMembershipInfoVo().getEndTime());
                }
                
                // 红娘信息
                exportVo.setMatchmakerFlag(Boolean.TRUE.equals(user.getMatchmakerFlag()) ? "是" : "否");
                if (user.getMatchmakerInfoVo() != null) {
                    exportVo.setMatchmakerNo(user.getMatchmakerInfoVo().getNo() + "");
                    exportVo.setMatchmakerPositionLevelName(user.getMatchmakerInfoVo().getPositionLevelName());
                    exportVo.setMatchmakerName(user.getMatchmakerInfoVo().getName());
                    exportVo.setMatchmakerBirthDate(user.getMatchmakerInfoVo().getBirthDate());
                    exportVo.setMatchmakerContactPhone(user.getMatchmakerInfoVo().getContactPhone());
                    exportVo.setMatchmakerEntryDate(user.getMatchmakerInfoVo().getEntryDate());
                    exportVo.setMatchmakerExpertise(user.getMatchmakerInfoVo().getExpertise());
                    
                    // 红娘性别处理：0是男，1是女
                    if ("0".equals(user.getMatchmakerInfoVo().getGender())) {
                        exportVo.setMatchmakerGender("男");
                    } else if ("1".equals(user.getMatchmakerInfoVo().getGender())) {
                        exportVo.setMatchmakerGender("女");
                    } else {
                        exportVo.setMatchmakerGender("");
                    }
                    
                    exportVo.setMatchmakerRegion(user.getMatchmakerRegion());
                }
                
                // 合伙人信息
                exportVo.setPartnerFlag(Boolean.TRUE.equals(user.getPartnerFlag()) ? "是" : "否");
                if (user.getOfflineServiceProviderVo() != null) {
                    exportVo.setPartnerName(user.getOfflineServiceProviderVo().getName());
                    exportVo.setPartnerTypeName(user.getOfflineServiceProviderVo().getPartnerTypeName());
                    exportVo.setPartnerStartTime(user.getOfflineServiceProviderVo().getStartTime());
                    exportVo.setPartnerEndTime(user.getOfflineServiceProviderVo().getEndTime());
                    exportVo.setPartnerPhoneNumber(user.getOfflineServiceProviderVo().getPhoneNumber());
                    exportVo.setPartnerDemandDescription(user.getOfflineServiceProviderVo().getDemandDescription());
                    
                    // 合伙人所在地通过省市县关联显示
                    String partnerResidence = "";
                    if (user.getOfflineServiceProviderVo().getProvinceName() != null) partnerResidence += user.getOfflineServiceProviderVo().getProvinceName();
                    if (user.getOfflineServiceProviderVo().getCityName() != null) partnerResidence += "/" + user.getOfflineServiceProviderVo().getCityName();
                    if (user.getOfflineServiceProviderVo().getDistrictName() != null) partnerResidence += "/" + user.getOfflineServiceProviderVo().getDistrictName();
                    exportVo.setPartnerResidence(partnerResidence.isEmpty() ? "" : partnerResidence);
                    
                    exportVo.setPartnerSingleFlag(Boolean.TRUE.equals(user.getOfflineServiceProviderVo().getSingleFlag()) ? "是" : "否");
                }
                return exportVo;
            }).collect(Collectors.toList());
            
            // 生成Excel文件
            ExportParams exportParams = new ExportParams("用户完整信息", "用户完整信息");
            Workbook workbook = ExcelExportUtil.exportExcel(exportParams, UserAllInfoExportVo.class, exportList);
            
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("用户完整信息_" + System.currentTimeMillis() + ".xlsx", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
            
            // 写入响应流
            workbook.write(response.getOutputStream());
            workbook.close();
        } catch (Exception e) {
            log.error("导出用户完整信息失败", e);
            throw new RuntimeException("导出失败", e);
        }
    }

}
